package cn.mw.cmdb.service.impl;

import cn.mw.cmdb.entity.InstanceInfo;
import cn.mw.cmdb.param.InstanceIdsParam;
import cn.mw.cmdb.service.InstanceSyncService;
import cn.mw.cmdb.service.ServiceAction;
import cn.mw.components.mongodb.tool.CriteriaWrapper;
import cn.mw.microMonitorCommon.entity.cmdb.DataSourceInstanceVo;
import cn.mw.microMonitorCommon.entity.cmdb.DataSourceVo;
import cn.mw.microMonitorCommon.enums.DatasourceSyncMethodEnum;
import cn.mw.microMonitorCommon.util.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class InstanceSyncDeleteServiceImpl implements InstanceSyncService {
    @Autowired
    private CmdbServiceManage cmdbServiceManage;

    @Autowired
    private MessageSource messageSource;

    @Override
    public DatasourceSyncMethodEnum getDatasourceSyncMethodEnum() {
        return DatasourceSyncMethodEnum.syncDelete;
    }

    @Override
    public List<DataSourceInstanceVo> syncInstances(DataSourceVo datasourceVo, Map<DataSourceInstanceVo, InstanceInfo> dataSource2InstanceInfoMap) throws Exception {
        List<DataSourceInstanceVo> resultList = new ArrayList<>();
        List<DataSourceInstanceVo> dataSourceInstanceVoList = new ArrayList<>(dataSource2InstanceInfoMap.keySet());
        if (CollectionUtils.isEmpty(dataSourceInstanceVoList)) {
            return resultList;
        }

        String webMonitorModelId = SpringUtils.getPropertiesValue("base.webMonitor.modelId");
        InstanceServiceImpl service = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        Query query = new Query(CriteriaWrapper.where(InstanceInfo::getModelId).is(datasourceVo.getTargetModelId()));
        if (!webMonitorModelId.equals(datasourceVo.getTargetModelId())) {
            List<String> updateHostIps = dataSourceInstanceVoList.stream().map(DataSourceInstanceVo::getHostIp).toList();
            query.addCriteria(CriteriaWrapper.where(InstanceInfo::getInBandIp).in(updateHostIps));
        }
        List<InstanceInfo> existsInstanceList = service.selectListByQuery(query);

        Map<String, InstanceInfo> key2InstanceMap;
        if (webMonitorModelId.equals(datasourceVo.getTargetModelId())) {
            key2InstanceMap = existsInstanceList.stream().filter(item -> StringUtils.hasText(item.getHttpTestId())).collect(
                    Collectors.toMap(InstanceInfo::getHttpTestId, item -> item, (existing, replace) -> existing));
        } else {
            key2InstanceMap = existsInstanceList.stream().filter(item -> StringUtils.hasText(item.getMonitorTypeId())).collect(
                    Collectors.toMap(InstanceInfo::getMonitorTypeId, item -> item, (existing, replace) -> existing));
        }

        List<String> deleteInstanceIds = new ArrayList<>();
        for (Map.Entry<DataSourceInstanceVo, InstanceInfo> entry : dataSource2InstanceInfoMap.entrySet()) {
            if (webMonitorModelId.equals(datasourceVo.getTargetModelId())) {
                // WEB监测实例使用httpTestId配置
                if (key2InstanceMap.containsKey(entry.getValue().getHttpTestId())) {
                    deleteInstanceIds.add(key2InstanceMap.get(entry.getValue().getHttpTestId()).getId());
                    entry.getKey().setAsyncResult(true);
                } else {
                    entry.getKey().setErrorMsg(messageSource.getMessage("instance-notexist-error", null, LocaleContextHolder.getLocale()));
                    entry.getKey().setAsyncResult(false);
                }
            } else {
                // 普通实例使用hostId匹配
                if (key2InstanceMap.containsKey(entry.getValue().getMonitorTypeId())) {
                    deleteInstanceIds.add(key2InstanceMap.get(entry.getValue().getMonitorTypeId()).getId());
                    entry.getKey().setAsyncResult(true);
                } else {
                    entry.getKey().setAsyncResult(false);
                    entry.getKey().setErrorMsg(messageSource.getMessage("instance-notexist-error", null, LocaleContextHolder.getLocale()));
                }
            }
            resultList.add(entry.getKey());
        }

        if (!CollectionUtils.isEmpty(deleteInstanceIds)) {
            InstanceIdsParam instanceIdsParam = new InstanceIdsParam();
            instanceIdsParam.setIds(deleteInstanceIds);
            cmdbServiceManage.service(instanceIdsParam, ServiceAction.batchRemove);
        }
        return resultList;
    }
}
